package com.ctyon.watchmanager.ui.activity;

import android.graphics.Color;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.ctyon.common.event.ChatMessageEvent;
import com.ctyon.common.util.DataUtil;
import com.ctyon.common.util.InputUtil;
import com.ctyon.watchmanager.BasicApp;
import com.ctyon.watchmanager.R;
import com.ctyon.watchmanager.databinding.FragmentChatBinding;
import com.ctyon.watchmanager.listener.ItemClickListener;
import com.ctyon.watchmanager.model.db.entity.ChatMessageEntity;
import com.ctyon.watchmanager.model.db.entity.LoginHistoryEntity;
import com.ctyon.watchmanager.present.ChatPresenter;
import com.ctyon.watchmanager.ui.adapter.ChatAdapter;
import com.ctyon.watchmanager.util.BytesUtil;
import com.ctyon.watchmanager.util.MyNotification;
import com.orhanobut.logger.Logger;
import com.umeng.analytics.MobclickAgent;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.util.List;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.LiveData;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import lee.com.mqttlibrary.mqtt.MQTTManager;

import static com.ctyon.common.container.ARouterPath.ROUTER_ACTIVITY_CHAT;
import static com.ctyon.watchmanager.util.MyNotification.CHAT_ID;

@Route(path = ROUTER_ACTIVITY_CHAT)
public class ChatActivity extends AppCompatActivity {

    private final String LTAG = "ChatActivity";

    private FragmentChatBinding mBinding;
    private ChatAdapter mAdapter;
    private String topic;
    private String managerId;
    private String text;
    private MediaRecorder recorder;
    private MediaPlayer player;
    private String recordPath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
            window.setNavigationBarColor(Color.TRANSPARENT);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }

        ARouter.getInstance().inject(this);
        EventBus.getDefault().register(this);

        mBinding = DataBindingUtil.setContentView(this, R.layout.fragment_chat);
        mBinding.setChatPresenter(chatPresenter);

        mAdapter = new ChatAdapter(itemClickListener);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(RecyclerView.VERTICAL);
        mBinding.chatRecycler.setLayoutManager(layoutManager);
        mBinding.chatRecycler.setAdapter(mAdapter);
        mBinding.chatRecycler.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                InputUtil.hideSoftInput(BasicApp.getInstance(), v);
            }
            return false;
        });

        topic = BasicApp.getInstance().getWatch().getMeid();
        managerId = String.valueOf(BasicApp.getInstance().getManager().getManagerId());

        mBinding.chatEdit.setOnTouchListener((v, event) -> {
            Log.d(LTAG, "onTouch : " + event.getAction());
            if (mBinding.getIsAudio()) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    Log.d(LTAG, "录音按下");
                    startRecord();
                } else if (event.getAction() == MotionEvent.ACTION_UP) {
                    Log.d(LTAG, "录音松开");
                    stopRecord(true);
                } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
                    Log.d(LTAG, "录音取消");
                    stopRecord(false);
                } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                    Log.d(LTAG, "录音滑动");
                }
                return true;
            }
            return false;
        });

        MyNotification.getInstance().clearNotificationById(CHAT_ID);

        loadHistory();
    }

    private void startRecord() {
        Log.d(LTAG, "startRecord");
        mBinding.setShow(true);
        try {
            recorder = new MediaRecorder();
            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置音源为Micphone
            recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);//设置封装格式
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //设置编码格式
            recorder.setOutputFile(recordPath = BytesUtil.getAmrFilePath());
            recorder.prepare();
            //录音
            recorder.start();
        } catch (Exception e) {
            Log.e(LTAG, "record ERROR : " + e);
        }
    }

    public void stopRecord(boolean send) {
        Log.d(LTAG, "stopRecord");
        mBinding.setShow(false);
        try {
            recorder.stop();
            recorder.release();
        } catch (Exception e) {
            Log.e(LTAG, "stopRecord ERROR : " + e);
        }
        File file = new File(recordPath);
        if (send) {
            Log.d(LTAG, "file.length = " + file.length());
            if (file.length() > 2000) {
                String nick = DataUtil.isEmptyOr(BasicApp.getInstance().getManager().getNickName()) ?
                        BasicApp.getInstance().getManager().getPhoneNumber() : BasicApp.getInstance().getManager().getNickName();
                MQTTManager.getInstance()
                        .sentMessage("send/server/"
                                        + topic + "/"
                                        + BasicApp.getInstance().getManager().getManagerId()
                                        + "/audio",
                                BytesUtil.packData(recordPath));
                MQTTManager.getInstance()
                        .sentMessage("send/app/"
                                        + topic + "/"
                                        + BasicApp.getInstance().getManager().getManagerId()
                                        + "/audio/"
                                        + nick,
                                BytesUtil.packData(recordPath));

                ChatMessageEntity chatMessageEntity = new ChatMessageEntity();
                chatMessageEntity.setMsgType(1);
                chatMessageEntity.setMsgContent(recordPath);
                chatMessageEntity.setInMsg(false);
                mAdapter.addChat(chatMessageEntity);
                mBinding.chatRecycler.scrollToPosition(mAdapter.getItemCount() - 1);

                final String msgContent = recordPath;
                BasicApp.getInstance().getAppExecutors().diskIO().execute(() -> {
                    ChatMessageEntity entity = new ChatMessageEntity(1, msgContent, false);
                    BasicApp.getInstance().getRepository().insertChatMessage(entity);
                });
            } else {
                Toast.makeText(this, "时间太短", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(this, "已取消", Toast.LENGTH_SHORT).show();
            if (file.exists()) {
                file.delete();
            }
        }
    }

    public void startPlay(String path) {
        Log.d(LTAG, "startPlay path = " + path);
        File file = new File(path);
        if (!file.exists() || file.length() <= 0) {
            Log.d(LTAG, "file is not exists");
            return;
        }
        if (null != player && player.isPlaying()) {
            stopPlay();
        }
        try {
            player = new MediaPlayer();
            player.setOnPreparedListener(mp -> {
                Log.d(LTAG, "setOnPreparedListener");
                mp.start();
            });
            player.setOnCompletionListener(mp -> {
                Log.d(LTAG, "setOnCompletionListener");
                player.release();
                player = null;
            });
            player.setOnErrorListener((mp, what, extra) -> {
                Log.d(LTAG, "setOnErrorListener what = " + what + "  extra = " + extra);
                return false;
            });
            //设置要播放的文件
            player.setDataSource(path);
            player.prepareAsync();
        } catch (Exception e) {
            Log.e(LTAG, "startPlay ERROR : " + e);
        }
    }

    public void stopPlay() {
        Log.d(LTAG, "stopPlay");
        player.stop();
        player.release();
        player = null;
    }

    private void loadHistory() {
        Observable.create((ObservableOnSubscribe<List<ChatMessageEntity>>) emitter -> {
            List<ChatMessageEntity> chatHistories = BasicApp.getInstance().getRepository().loadChatHistory();
            if (null != chatHistories) {
                Log.d(LTAG, "size = " + chatHistories.size());
                if (chatHistories.size() > 0) {
                    emitter.onNext(chatHistories);
                }
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(o -> {
                    Log.d(LTAG, "subscribe");
                    mAdapter.setChatList(o);
                    mBinding.chatRecycler.scrollToPosition(mAdapter.getItemCount() - 1);
                });
    }

    public void onBackClick(View view) {
        finish();
    }

    private final ItemClickListener<Integer> itemClickListener = (index) -> {
        Logger.t(LTAG).d("id = " + index);
        ChatMessageEntity entity = mAdapter.getItem(index);
        if (entity.getMsgType() == 1) {
            Logger.t(LTAG).d("path = " + entity.getMsgContent());
            startPlay(entity.getMsgContent());
        }
    };

    private final ChatPresenter chatPresenter = new ChatPresenter() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            Logger.t(LTAG).d("onTextChanged : s = " + s);

            if (null != s && s.length() > 0) {
                text = s.toString().trim();
                if (!mBinding.getSendAble()) {
                    mBinding.setSendAble(true);
                }
            } else {
                if (mBinding.getSendAble()) {
                    mBinding.setSendAble(false);
                }
            }

        }

        @Override
        public void onSendButtonClick() {
            if (null != text && text.length() > 0) {
                String nick = DataUtil.isEmptyOr(BasicApp.getInstance().getManager().getNickName()) ?
                        BasicApp.getInstance().getManager().getPhoneNumber() : BasicApp.getInstance().getManager().getNickName();
                MQTTManager.getInstance()
                        .sentMessage("send/server/"
                                        + topic + "/"
                                        + BasicApp.getInstance().getManager().getManagerId() + "/text",
                                DataUtil.string2Unicode(text));
                MQTTManager.getInstance()
                        .sentMessage("send/app/"
                                        + topic + "/"
                                        + BasicApp.getInstance().getManager().getManagerId()
                                        + "/text/"
                                        + nick,
                                DataUtil.string2Unicode(text));

                ChatMessageEntity chatMessageEntity = new ChatMessageEntity();
                chatMessageEntity.setMsgType(0);
                chatMessageEntity.setMsgContent(text);
                chatMessageEntity.setInMsg(false);
                mAdapter.addChat(chatMessageEntity);
                mBinding.chatRecycler.scrollToPosition(mAdapter.getItemCount() - 1);

                final String msgContent = text;
                BasicApp.getInstance().getAppExecutors().diskIO().execute(() -> {
                    ChatMessageEntity entity = new ChatMessageEntity(0, msgContent, false);
                    BasicApp.getInstance().getRepository().insertChatMessage(entity);
                });

                text = "";
                mBinding.chatEdit.setText("");
            }
        }

        @Override
        public void onInputTypeClick(View view) {
            if (mBinding.getIsAudio()) {
                mBinding.setIsAudio(false);
            } else {
                mBinding.chatEdit.clearFocus();
                mBinding.setIsAudio(true);
                InputUtil.hideSoftInput(BasicApp.getInstance(), view);
            }
        }

    };

    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    public void mqttData(ChatMessageEvent chatMessageEvent) {
        String type = chatMessageEvent.getType();// send/app/watchId/managerId/type
        String nick = chatMessageEvent.getFrom();// send/app/watchId/managerId/type/nick
        byte[] data = chatMessageEvent.getData();

        ChatMessageEntity chatMessageEntity = null;
        if (type.equals("text")) {
            chatMessageEntity = new ChatMessageEntity();
            chatMessageEntity.setMsgType(0);
            chatMessageEntity.setMsgContent(DataUtil.unicode2String(new String(data)));
        } else if (type.equals("audio")) {
            Logger.t(LTAG).d("aduio 长度 = " + data.length);
            String path = BytesUtil.unpackData(0, data);
            chatMessageEntity = new ChatMessageEntity();
            chatMessageEntity.setMsgType(1);
            chatMessageEntity.setMsgContent(path);
        } else {
            Logger.t(LTAG).e("未知消息类型");
        }

        if (null != chatMessageEntity) {
            chatMessageEntity.setInMsg(true);
            chatMessageEntity.setMsgNick(nick);
            mAdapter.addChat(chatMessageEntity);
            mBinding.chatRecycler.scrollToPosition(mAdapter.getItemCount() - 1);
        }

    }

    @Override
    protected void onStop() {
        super.onStop();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        if (null != recorder) {
            recorder = null;
        }
        if (null != player) {
            if (player.isPlaying()) {
                player.stop();
            }
            player.release();
            player = null;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        MobclickAgent.onResume(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        MobclickAgent.onPause(this);
    }

}
